package cn.neusoft.service.impl;

import cn.neusoft.domain.Operator;
import cn.neusoft.enums.Role;
import cn.neusoft.enums.Sex;
import cn.neusoft.enums.Status;
import cn.neusoft.exception.AppException;
import cn.neusoft.exception.AppExceptionCodeMsg;
import cn.neusoft.mapper.DeptMapper;
import cn.neusoft.mapper.OperatorMapper;
import cn.neusoft.query.BaseQuery;
import cn.neusoft.service.OperatorService;
import cn.neusoft.util.EnumUtils;
import cn.neusoft.util.UUIDUtils;
import cn.neusoft.vo.PageBean;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

@Service
@Slf4j
public class OperatorServiceImpl implements OperatorService {

    @Autowired
    OperatorMapper operatorMapper;

    @Autowired
    DeptMapper deptMapper;

//    @Autowired
//    private SmsConstantUtils smsConstantUtils;
//
//    @Autowired
//    private RedisTemplate<String, String> redisTemplate;


    /*
            密码校验正则表达式，要求：
                1. 密码中不含有空格
                2. 密码长度为8-16位
                3. 密码必须包含字母、数字、符号中至少两种
         */
    private final String passwordPattern = "^(?![a-zA-Z]+$)(?!\\d+$)(?![^\\da-zA-Z\\s]+$)(?!.*\\s).{8,16}$";
    /*
        手机号校验正则表达式
     */
    private final String telPattern = "^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\\d{8}$";

    /**
     * 新增员工
     *
     * @param operator
     */
    @Transactional
    @Override
    public void add(Operator operator) {

        // 状态参数非法
        if (!EnumUtils.isInclude(Status.class, operator.getStatus())) {
            throw new AppException(AppExceptionCodeMsg.OPERATOR_STATUS_INVALID);
        }

        // 性别参数非法
        if (!EnumUtils.isInclude(Sex.class, operator.getSex())) {
            throw new AppException(AppExceptionCodeMsg.OPERATOR_SEX_INVALID);
        }

        // 密码不符合要求
        if (!operator.getOperator_password().matches(passwordPattern)) {
            throw new AppException(AppExceptionCodeMsg.OPERATOR_PASSWORD_INVALID);
        }

        // 手机号非法
        if (!operator.getTel().matches(telPattern)) {
            throw new AppException(AppExceptionCodeMsg.OPERATOR_TEL_INVALID);
        }

        // 账户名重复
        if (operatorMapper.checkAccountUnique(operator.getOperator_account()) != null) {
            throw new AppException(AppExceptionCodeMsg.OPERATOR_ACCOUNT_DUPLICATED);
        }

        // 手机号重复
        if (operatorMapper.checkTelUnique(operator.getTel()) != null) {
            throw new AppException(AppExceptionCodeMsg.OPERATOR_TEL_DUPLICATED);
        }

        // 部门不存在
        if (deptMapper.findById(operator.getDept_id()) == null) {
            throw new AppException(AppExceptionCodeMsg.DEPT_NOT_EXISTS);
        }

        // 角色（role）不存在
        if (!EnumUtils.isInclude(Role.class, operator.getRole_id())){
            throw new AppException(AppExceptionCodeMsg.ROLE_NOT_EXITS);
        }

        operator.setOperator_id(UUIDUtils.getUUID());

        operatorMapper.add(operator);
    }

    /**
     * 根据id修改员工信息
     *
     * @param operator
     */
    @Transactional
    @Override
    public void update(Operator operator) {

        // 状态参数非法
        if (!EnumUtils.isInclude(Status.class, operator.getStatus())) {
            throw new AppException(AppExceptionCodeMsg.OPERATOR_STATUS_INVALID);
        }

        // 性别参数非法
        if (!EnumUtils.isInclude(Sex.class, operator.getSex())) {
            throw new AppException(AppExceptionCodeMsg.OPERATOR_SEX_INVALID);
        }

        // 密码不符合要求
        if (!operator.getOperator_password().matches(passwordPattern)) {
            throw new AppException(AppExceptionCodeMsg.OPERATOR_PASSWORD_INVALID);
        }

        // 手机号非法
        if (!operator.getTel().matches(telPattern)) {
            throw new AppException(AppExceptionCodeMsg.OPERATOR_TEL_INVALID);
        }

        // 不存在id为传入值的员工
        if (operatorMapper.findById(operator.getOperator_id()) == null) {
            throw new AppException(AppExceptionCodeMsg.OPERATOR_NOT_EXISTS);
        }

        // 账户重复【需要排除自己】
        Operator sameAccountOperator = operatorMapper.checkAccountUnique(operator.getOperator_account());
        if (sameAccountOperator != null &&
                !Objects.equals(operator.getOperator_id(), sameAccountOperator.getOperator_id())) {
            throw new AppException(AppExceptionCodeMsg.OPERATOR_ACCOUNT_DUPLICATED);
        }

        // 手机号重复【排除自己】
        Operator sameTelOperator = operatorMapper.checkTelUnique(operator.getTel());
        if (sameTelOperator != null &&
                !Objects.equals(operator.getOperator_id(), sameTelOperator.getOperator_id())) {
            throw new AppException(AppExceptionCodeMsg.OPERATOR_TEL_DUPLICATED);
        }

        // 部门不存在
        if (deptMapper.findById(operator.getDept_id()) == null) {
            throw new AppException(AppExceptionCodeMsg.DEPT_NOT_EXISTS);
        }

        // 角色（role）不存在
        if (!EnumUtils.isInclude(Role.class, operator.getRole_id())){
            throw new AppException(AppExceptionCodeMsg.ROLE_NOT_EXITS);
        }

        operatorMapper.update(operator);
    }

    @Override
    public void updateStatus(Operator operator) {
        // 状态参数非法
        if (!EnumUtils.isInclude(Status.class, operator.getStatus())) {
            throw new AppException(AppExceptionCodeMsg.OPERATOR_STATUS_INVALID);
        }

        // 防止有其他信息
        Operator operator1 = new Operator();
        operator1.setOperator_id(operator.getOperator_id());
        operator1.setStatus(operator.getStatus());

        operatorMapper.update(operator1);
    }

    /**
     * 根据id删除员工
     *
     * @param operator_id
     */
    @Transactional
    @Override
    public void deleteById(String operator_id) {
        // TODO: 根据角色（role）判断能不能删除，例如超级管理员不能删

        operatorMapper.deleteById(operator_id);
    }

    /**
     * 查询所有员工信息
     *
     * @return
     */
    @Transactional
    @Override
    public List<Operator> findAll() {
        return operatorMapper.findAll();
    }

    /**
     * 根据id查询员工信息
     *
     * @param operator_id
     * @return
     */
    @Transactional
    @Override
    public Operator findById(String operator_id) {
        return operatorMapper.findById(operator_id);
    }

    @Transactional
    @Override
    public Operator findByAccount(String operator_account) {
        return operatorMapper.findByAccount(operator_account);
    }

    @Transactional
    @Override
    public Operator findByTel(String tel) {
        return operatorMapper.findByTel(tel);
    }

//    @Transactional
//    @Override
//    public Map<String, Object> loginByPwd(String operator_account, String operator_password) {
//
//        Operator operator = operatorMapper.findByAccount(operator_account);
//
//        // 账号不存在
//        if (operator == null) {
//            throw new AppException(AppExceptionCodeMsg.OPERATOR_ACCOUNT_NOT_EXITS);
//        }
//
//        // 账号密码不匹配
//        if (!Objects.equals(operator_password, operator.getOperator_password())) {
//            throw new AppException(AppExceptionCodeMsg.OPERATOR_ACCOUNT_PASSWORD_WRONG);
//        }
//
//        // 登录成功
//        List<Menu> menuList = operatorMapper.getMenuListByRoleId(String.valueOf(operator.getRole_id()));
//        Map<String, Object> map = new HashMap<>();
//        map.put("user", operator);
//        map.put("menu", menuList);
//
//        return map;
//    }
//
//
//    @Transactional
//    @Override
//    public Map<String, Object> loginByTel(String tel, String code) {
//        Operator operator = operatorMapper.findByTel(tel);
//
//        // 手机号不存在
//        if (operator == null){
//            throw new AppException(AppExceptionCodeMsg.OPERATOR_TEL_NOT_EXITS);
//        }
//
//        // 验证码错误
//        if(!Objects.equals(code, redisTemplate.opsForValue().get(tel))){
//            throw new AppException(AppExceptionCodeMsg.INVOID_CODE);
//        }
//
//        // 登录成功
//        List<Menu> menuList = operatorMapper.getMenuListByRoleId(String.valueOf(operator.getRole_id()));
//        Map<String, Object> map = new HashMap<>();
//        map.put("user", operator);
//        map.put("menu", menuList);
//
//        return map;
//    }


    /**
     * 分页模糊查询员工信息
     *
     * @param query
     * @return
     */
    @Transactional
    @Override
    public PageBean<Operator> findByPage(BaseQuery query) {

        // 构建结果对象
        PageBean<Operator> pageBean = new PageBean<>();

        // 开启分页
        PageHelper.startPage(query.getPageNow(), query.getPageSize());

        // 查询得到当前页的集合
        List<Operator> operatorList = operatorMapper.findByCondition(query);

        // 创建一个分页的实体PageInfo
        PageInfo<Operator> pageInfo = new PageInfo<>(operatorList);

        pageBean.setTotalRows(pageInfo.getTotal());
        pageBean.setTotalPages(pageInfo.getPages());
        pageBean.setRowData(pageInfo.getList());

        return pageBean;
    }

//    @Transactional
//    @Override
//    public void send(String phone, String[] params) {
//        String phoneNumber = "+86" + phone;
//        String secretId = smsConstantUtils.getSecretId();
//        String secretKey = smsConstantUtils.getSecretKey();
//        String sdkAppId = smsConstantUtils.getSdkAppId();
//        String signName = smsConstantUtils.getSignName();
//        String templateId = smsConstantUtils.getTemplateId();
//
//        String[] phoneNumberSet = {phoneNumber};
//        String[] templateParamSet = params;//对应模板中{1}{2}
//
//        try {
//            /* 必要步骤：
//             * 实例化一个认证对象，入参需要传入腾讯云账户密钥对secretId，secretKey。
//             * 这里采用的是从环境变量读取的方式，需要在环境变量中先设置这两个值。
//             * 你也可以直接在代码中写死密钥对，但是小心不要将代码复制、上传或者分享给他人，
//             * 以免泄露密钥对危及你的财产安全。
//             * SecretId、SecretKey 查询: https://console.cloud.tencent.com/cam/capi */
//            Credential cred = new Credential(secretId, secretKey);
//
//            // 实例化一个http选项，可选，没有特殊需求可以跳过
//            HttpProfile httpProfile = new HttpProfile();
//            // 设置代理（无需要直接忽略）
//            // httpProfile.setProxyHost("真实代理ip");
//            // httpProfile.setProxyPort(真实代理端口);
//            /* SDK默认使用POST方法。
//             * 如果你一定要使用GET方法，可以在这里设置。GET方法无法处理一些较大的请求 */
//            httpProfile.setReqMethod("POST");
//            /* SDK有默认的超时时间，非必要请不要进行调整
//             * 如有需要请在代码中查阅以获取最新的默认值 */
//            httpProfile.setConnTimeout(60);
//            /* 指定接入地域域名，默认就近地域接入域名为 sms.tencentcloudapi.com ，也支持指定地域域名访问，例如广州地域的域名为 sms.ap-guangzhou.tencentcloudapi.com */
//            httpProfile.setEndpoint("sms.tencentcloudapi.com");
//
//            /* 非必要步骤:
//             * 实例化一个客户端配置对象，可以指定超时时间等配置 */
//            ClientProfile clientProfile = new ClientProfile();
//            /* SDK默认用TC3-HMAC-SHA256进行签名
//             * 非必要请不要修改这个字段 */
//            clientProfile.setSignMethod("HmacSHA256");
//            clientProfile.setHttpProfile(httpProfile);
//            /* 实例化要请求产品(以sms为例)的client对象
//             * 第二个参数是地域信息，可以直接填写字符串ap-guangzhou，支持的地域列表参考 https://cloud.tencent.com/document/api/382/52071#.E5.9C.B0.E5.9F.9F.E5.88.97.E8.A1.A8 */
//            SmsClient client = new SmsClient(cred, "ap-guangzhou", clientProfile);
//            /* 实例化一个请求对象，根据调用的接口和实际情况，可以进一步设置请求参数
//             * 你可以直接查询SDK源码确定接口有哪些属性可以设置
//             * 属性可能是基本类型，也可能引用了另一个数据结构
//             * 推荐使用IDE进行开发，可以方便的跳转查阅各个接口和数据结构的文档说明 */
//            SendSmsRequest req = new SendSmsRequest();
//
//            /* 填充请求参数,这里request对象的成员变量即对应接口的入参
//             * 你可以通过官网接口文档或跳转到request对象的定义处查看请求参数的定义
//             * 基本类型的设置:
//             * 帮助链接：
//             * 短信控制台: https://console.cloud.tencent.com/smsv2
//             * 腾讯云短信小助手: https://cloud.tencent.com/document/product/382/3773#.E6.8A.80.E6.9C.AF.E4.BA.A4.E6.B5.81 */
//
//            /* 短信应用ID: 短信SdkAppId在 [短信控制台] 添加应用后生成的实际SdkAppId，示例如1400006666 */
//            // 应用 ID 可前往 [短信控制台](https://console.cloud.tencent.com/smsv2/app-manage) 查看
//            req.setSmsSdkAppId(sdkAppId);
//
//            /* 短信签名内容: 使用 UTF-8 编码，必须填写已审核通过的签名 */
//            // 签名信息可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-sign) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-sign) 的签名管理查看
//            req.setSignName(signName);
//
//            /* 模板 ID: 必须填写已审核通过的模板 ID */
//            // 模板 ID 可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-template) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-template) 的正文模板管理查看
//            req.setTemplateId(templateId);
//
//            /* 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致，若无模板参数，则设置为空 */
//            req.setTemplateParamSet(templateParamSet);
//
//            /* 下发手机号码，采用 E.164 标准，+[国家或地区码][手机号]
//             * 示例如：+8613711112222， 其中前面有一个+号 ，86为国家码，13711112222为手机号，最多不要超过200个手机号 */
//            req.setPhoneNumberSet(phoneNumberSet);
//
//            /* 通过 client 对象调用 SendSms 方法发起请求。注意请求方法名与请求对象是对应的
//             * 返回的 res 是一个 SendSmsResponse 类的实例，与请求对象对应 */
//            SendSmsResponse res = client.SendSms(req);
//            //获取响应结果
//            SendStatus[] sendStatusSet = res.getSendStatusSet();
//            // 输出json格式的字符串回包
//            System.out.println(SendSmsResponse.toJsonString(res));
//            log.info("短信发送返回的响应："+ Arrays.toString(sendStatusSet));
//        } catch (TencentCloudSDKException e) {
//            log.error("腾讯云短信发送sdk调用失败："+e.getErrorCode()+","+e.getMessage());
//            throw new AppException(AppExceptionCodeMsg.CODE_SEND_FAILED);
//        }
//    }
}
